/***************************************************************************
      File Name:  OptionMenu.cs
   File Created:  Wednesday, June 13th 2007
      Copyright:  (C) 2007 by Darko Matesic
          Email:  darko.matesic@yahoo.com
 ***************************************************************************/

using System;
using System.Drawing;
using System.Windows.Forms;

namespace CallerID.Helpers
{
    public class OptionMenu
    {
        /// <summary>
        /// Displays context menu with items defined in string array, and when an item is click optionMenuCallback method is called
        /// </summary>
        public static void Show(string[] options, bool[] enabled, OptionMenuCallback optionMenuCallback, Point position, ToolStripDropDownDirection toolStripDropDownDirection, bool showImageMargin)
        {
            OptionMenuHandler handler = new OptionMenuHandler(options, enabled, optionMenuCallback, showImageMargin);
            handler.Show(position, toolStripDropDownDirection);
        }
        /// <summary>
        /// Displays context menu with items defined in string array, and when an item is click optionMenuCallback method is called
        /// </summary>
        public static void Show(string[] options, bool[] enabled, OptionMenuCallback optionMenuCallback, Control control, ToolStripDropDownDirection toolStripDropDownDirection, bool showImageMargin)
        {
            Show(options, enabled, optionMenuCallback, GetPosition(control, toolStripDropDownDirection), toolStripDropDownDirection, showImageMargin);
        }

        /// <summary>
        /// Displays context menu with items defined in string array, and when an item is click optionMenuCallback method is called
        /// </summary>
        public static void Show(string[] options, OptionMenuCallback optionMenuCallback, Point position, ToolStripDropDownDirection toolStripDropDownDirection, bool showImageMargin)
        {
            Show(options, null, optionMenuCallback, position, toolStripDropDownDirection, showImageMargin);
        }
        /// <summary>
        /// Displays context menu with items defined in string array, and when an item is click optionMenuCallback method is called
        /// </summary>
        public static void Show(string[] options, OptionMenuCallback optionMenuCallback, Control control, ToolStripDropDownDirection toolStripDropDownDirection, bool showImageMargin)
        {
            Show(options, null, optionMenuCallback, GetPosition(control, toolStripDropDownDirection), toolStripDropDownDirection, showImageMargin);
        }

        /// <summary>
        /// Displays context menu with items defined in string array, and when an item is click optionMenuCallback method is called
        /// </summary>
        public static void Show(string[] options, bool[] enabled, OptionMenuCallback optionMenuCallback, bool showImageMargin)
        {
            Show(options, enabled, optionMenuCallback, Cursor.Position, ToolStripDropDownDirection.Default, showImageMargin);
        }
        /// <summary>
        /// Displays context menu with items defined in string array, and when an item is click optionMenuCallback method is called
        /// </summary>
        public static void Show(string[] options, OptionMenuCallback optionMenuCallback, bool showImageMargin)
        {
            Show(options, null, optionMenuCallback, Cursor.Position, ToolStripDropDownDirection.Default, showImageMargin);
        }

        /// <summary>
        /// Displays context menu with items defined in string array, and when an item is click optionMenuCallback method is called
        /// </summary>
        public static void Show(string[] options, bool[] enabled, OptionMenuCallback optionMenuCallback)
        {
            Show(options, enabled, optionMenuCallback, Cursor.Position, ToolStripDropDownDirection.Default, true);
        }
        /// <summary>
        /// Displays context menu with items defined in string array, and when an item is click optionMenuCallback method is called
        /// </summary>
        public static void Show(string[] options, OptionMenuCallback optionMenuCallback)
        {
            Show(options, null, optionMenuCallback, Cursor.Position, ToolStripDropDownDirection.Default, true);
        }


        /// <summary>
        /// Returns position for menu based on specified control and direction.
        /// </summary>
        private static Point GetPosition(Control control, ToolStripDropDownDirection direction)
        {
            if(control != null) {
                switch(direction) {
                    case ToolStripDropDownDirection.AboveLeft:
                        return control.PointToScreen(new Point(control.Width, 0));
                    case ToolStripDropDownDirection.AboveRight:
                        return control.PointToScreen(new Point(0, 0));
                    case ToolStripDropDownDirection.Left:
                    case ToolStripDropDownDirection.BelowLeft:
                        return control.PointToScreen(new Point(control.Width, control.Height));
                    case ToolStripDropDownDirection.Right:
                    case ToolStripDropDownDirection.BelowRight:
                        return control.PointToScreen(new Point(0, control.Height));
                }
            }
            return Cursor.Position;
        }

        /// <summary>
        /// Private class for handling option menu
        /// </summary>
        private class OptionMenuHandler
        {
            private OptionMenuCallback optionMenuCallbackMethod = null;
            private ToolStripDropDownMenu optionMenu = null;

            public OptionMenuHandler(string[] options, bool[] enabled, OptionMenuCallback optionMenuCallback, bool showImageMargin)
            {
                try {
                    optionMenuCallbackMethod = optionMenuCallback;
                    optionMenu = new ToolStripDropDownMenu();
                    optionMenu.ShowItemToolTips = false;
                    if(showImageMargin == false) {
                        optionMenu.ShowCheckMargin = false;
                        optionMenu.ShowImageMargin = false;
                    }
                    //optionMenu.RenderMode = ToolStripRenderMode.Professional;
                    int index = 0;
                    for(int i = 0; i < options.Length; i++) {
                        string option = options[i];
                        ToolStripMenuItem optionMenuItem = new ToolStripMenuItem(option.Trim());
                        optionMenuItem.ShowShortcutKeys = false;
                        if(option != "-") {
                            optionMenuItem.Tag = index++;
                            optionMenuItem.Click += new EventHandler(optionMenuItem_Click);
                            if(enabled != null && enabled.Length >= (i + 1) && enabled[i] == false) optionMenuItem.Enabled = false;
                        }
                        optionMenu.Items.Add(optionMenuItem);
                    }
                } catch { }
            }

            public void Show(Point position, ToolStripDropDownDirection toolStripDropDownDirection)
            {
                if(optionMenu != null) {
                    optionMenu.Show(position, toolStripDropDownDirection);
                }
            }

            private void optionMenuItem_Click(object sender, EventArgs e)
            {
                int index = -1;
                try { index = (int)((ToolStripMenuItem)sender).Tag; } catch { }
                if(optionMenuCallbackMethod != null) optionMenuCallbackMethod(index);
                try { optionMenu.Dispose(); optionMenu = null; } catch { }
            }
        }

    }

    /// <summary>
    /// Delegate used for callback method that is called when user clicks menu option.
    /// </summary>
    public delegate void OptionMenuCallback(int selectedOptionIndex);
}
